package com.yzs.exam.entity.exam;

import com.yzs.exam.common.exception.BusinessException;
import com.yzs.exam.context.WebContext;
import com.yzs.exam.entity.Question;
import com.yzs.exam.entity.enums.ExamPaperWeightEnum;
import com.yzs.exam.entity.enums.QuestionTypeEnum;
import com.yzs.exam.repository.QuestionMapper;
import com.yzs.exam.service.QuestionService;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.parsing.Problem;

import java.awt.*;
import java.io.Serializable;
import java.util.List;
import java.util.Random;

/**
 * 种群：即多套试卷
 * @author yzs
 * @create 2021-04-28 11:27
 */
public class Population implements Serializable {
    private ExamPaperAlgotithmBean[] papers;

    public ExamPaperAlgotithmBean[] getPapers() {
        return papers;
    }

    public Population(int populationSize) {
        papers = new ExamPaperAlgotithmBean[populationSize];
    }
    /**
     * 初始化种群
     * @param populationSize 种群数量
     * @param initFlag 初始化标志： true=初始化
     * @param rule 种群规则bean
     */
    public Population(int populationSize, boolean initFlag, Rule rule,List<List<Question>> lists) {
        papers = new ExamPaperAlgotithmBean[populationSize];
        if (initFlag){
            ExamPaperAlgotithmBean paper;
            Random random = new Random();
            List<Question> questions1 = lists.get(0);
            List<Question> questions2 = lists.get(1);
            List<Question> questions3 = lists.get(2);
            List<Question> questions4 = lists.get(3);
            List<Question> questions5 = lists.get(4);

            for (int i = 0; i < populationSize; i++){
                paper =  new ExamPaperAlgotithmBean();
                paper.setId(i + 1);
                //试卷总分 ！= 规定试卷总分 -- 继续迭代
                while (paper.getTotalScore() != ((double) rule.getTotalScore())) {
                    paper.getQuestions().clear();
                    List<Integer> chapters = rule.getChapters();
                    if (rule.getChoiceNum() > 0){
                        generateQuestion(random,rule.getChoiceNum()/3,
                                "单选题数量不够，组卷失败",paper,questions1);
                        generateQuestion(random,rule.getChoiceNum()/3,
                                "多选题数量不够，组卷失败",paper,questions2);
                        generateQuestion(random,rule.getChoiceNum()/3,
                                "判断题数量不够，组卷失败",paper,questions3);
                    }
                    if (rule.getFillingNum() > 0){
                        generateQuestion(random,rule.getFillingNum(),
                                "填空题数量不够，组卷失败",paper,questions4);
                    }
                    if (rule.getChoiceNum() > 0){
                        generateQuestion(random,rule.getAnswerNum(),
                                "简答题数量不够，组卷失败",paper,questions5);
                    }
                    List<Question> questions = paper.getQuestions();
                    paper.setChapterCoverage(rule);
                    paper.setAdaptationDegree(rule, ExamPaperWeightEnum.CHAPTER_WEIGHT,ExamPaperWeightEnum.DIFFICULTY_WEIGHT);
                    papers[i] = paper;
                }
            }
        }
        
    }

    /**
     * 生成问题
     * @param random 随机对象
     * @param questionNum 问题个数
     */
    private void generateQuestion(Random random, int questionNum, String errMsg, ExamPaperAlgotithmBean paper,List<Question> questions){
        if (questions.size() < questionNum){
            throw new BusinessException(errMsg);
        }
        Question tempQuestion;
        for (int j = 0; j < questionNum; j++){
            int index = random.nextInt(questions.size() - j);
            Question question = questions.get(index);
            paper.addQuestion(question);
            //保证随机不重复
            tempQuestion = questions.get(questions.size() - j - 1);
            questions.set(questions.size() - j - 1,question);
            questions.set(index,tempQuestion);
        }
    }

    /**
     * 得到种群中最优个体
     * 遍历找到种群中适应度最高的个体
     * @return
     */
    public ExamPaperAlgotithmBean getFitness(){
        ExamPaperAlgotithmBean paper = papers[0];
        for(int i = 1; i < papers.length; i++){
            if (paper.getAdaptationDegree() < papers[i].getAdaptationDegree()){
                paper = papers[i];
            }
        }
        return paper;
    }

    /**
     * 获取种群中某个个体
     *
     * @param index
     * @return
     */
    public ExamPaperAlgotithmBean getPaper(int index) {
        return papers[index];
    }

    /**
     * 设置种群中某个个体
     *
     * @param index
     * @param paper
     */
    public void setPaper(int index, ExamPaperAlgotithmBean paper) {
        papers[index] = paper;
    }

    /**
     * 返回种群规模
     *
     * @return
     */
    public int getLength() {
        return papers.length;
    }
}
